package wh.coach._exception;

import java.util.Arrays;

/**
 * @author hangwen
 * @date 2023/7/6
 */
public class Main {

    static {

    }

//    private static final MyClass xxx= new MyClass();

    public static void main(String[] args) {
        //异常的本质
        //1.中断当前执行的代码，等价于return 一个 throwable；
        //2.存储调用栈,也可以包含其他信息，取决于exception类的设计
        //3.异常如没有被catch，最终会被线程的UncaughtExceptionHandler处理，UncaughtExceptionHandler可以自定义，但最终线程一定会终止
        Thread.currentThread().setUncaughtExceptionHandler((t, e) -> {
            System.out.println("线程" + t.getName() + ",出现了异常");
            System.out.println(Arrays.toString(e.getStackTrace()));
        });

//        fun1();

        //4.异常像一个气泡,被catch时，才会停止冒泡
        //5.catch后，异常可以选择继续throw，也可以不throw
        catchError(Main::fun1);//这是类似函数指针的写法

        //异常的类型
        //Throwable
        //  Error 系统级错误，比如：内存用完、类初始化异常(只执行一次)
        //  Exception 需要显式处理 又叫checked异常 比如IO异常
        //      RuntimeException 无须显式，它的出现往往意味的代码写得有问题

//        fun3();

        //问题1：如何处理异常
        //a.对于checked异常
        //1.变成一个runtimeException，抛出
        //2.兜底一个值，但是需要打印日志，即：吃掉了异常
        // 3.如果在程序的运行中，重要的是记录异常，可以将可能发生异常的地方进行一个返回值的自定义，使程序可以继续进行下去
        // 4.使用try -catch直接捕获异常直接处理

        //问题2：自定义异常的场景
        //1.验证输入， 例如让用户输入一个电话号码，用户输入不正确就可以进行多次输入直至正确。
        //2.文件操作， 假如找一个文件进行操作需要判断文件是否存在
        //3.数据库操作， 比如创建一个表很有可能创建了相同的表

        System.out.println("app end");
    }

    private static void catchError(final Runnable runnable) {
        try {
            runnable.run();
        } catch (Exception ex) {
//            System.out.println("线程" + t.getName() + ",出现了异常");
            System.out.println(Arrays.toString(ex.getStackTrace()));
        }
    }

    private static void fun1() {
        fun2();
    }

    private static void fun2() {
        throw new RuntimeException("fun2 exception");
    }

    private static void fun3() throws MyException {
        throw new MyException();
    }

}
